package com.jichangxiu.server.platform.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jichangxiu.common.entity.bo.PageData;
import com.jichangxiu.common.exception.ServiceException;
import com.jichangxiu.common.utils.StrUtils;
import com.jichangxiu.common.utils.TokenUtils;
import com.jichangxiu.framework.mybatis.BaseServiceImpl;
import com.jichangxiu.server.platform.entity.dto.PlatformDictTypeQueryDto;
import com.jichangxiu.server.platform.entity.map.PlatformDictTypeBasic;
import com.jichangxiu.server.platform.entity.po.PlatformDictType;
import com.jichangxiu.server.platform.entity.po.PlatformTenant;
import com.jichangxiu.server.platform.entity.vo.PlatformDictTypeAddVo;
import com.jichangxiu.server.platform.entity.vo.PlatformDictTypeEditVo;
import com.jichangxiu.server.platform.entity.vo.PlatformDictTypeQueryVo;
import com.jichangxiu.server.platform.mapper.PlatformDictTypeMapper;
import com.jichangxiu.server.platform.service.PlatformDictTypeService;
import com.jichangxiu.server.platform.service.PlatformTenantService;
import com.jichangxiu.server.platform.service.PlatformUserService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

/**
 * PlatformDictTypeServiceImpl:
 *
 * @author Jcx
 * @create 2023-03-08 21:17
 */
@Service
public class PlatformDictTypeServiceImpl extends BaseServiceImpl<PlatformDictTypeMapper, PlatformDictType> implements PlatformDictTypeService {

    @Resource
    private StrUtils strUtils;

    @Resource
    private TokenUtils tokenUtils;

    @Resource
    private PlatformDictTypeMapper platformDictTypeMapper;

    @Resource
    private PlatformTenantService platformTenantService;

    @Resource
    private PlatformUserService platformUserService;

    /**
     * 新增字典类型
     *
     * @param platformDictTypeAddVo 字典类型视图对象
     * @return 是否成功
     */
    @Override
    public Boolean add(PlatformDictTypeAddVo platformDictTypeAddVo) {
        if (ObjectUtil.isEmpty(platformDictTypeAddVo)) {
            throw ServiceException.build("字典类型对象无效");
        }

        PlatformDictType platformDictType = PlatformDictTypeBasic.INSTANCE.toPlatformDictType(platformDictTypeAddVo);
        if (ObjectUtil.isEmpty(platformDictType)) {
            throw ServiceException.build("字典类型对象无效");
        }

        if ("PLATFORM_DICT".equals(platformDictType.getDictType())) {
            PlatformTenant platformTenant = platformTenantService.getOne(new LambdaQueryWrapper<PlatformTenant>().eq(PlatformTenant::getTenantId, tokenUtils.getTenantId()));
            if (ObjectUtil.isEmpty(platformTenant)) {
                throw ServiceException.build("获取租户失败");
            }
            if (!platformTenant.getIsPlatform()) {
                throw ServiceException.build("非平台级租户不能创建平台级字典类型");
            }
        }

        // Code 必须唯一
        PlatformDictType dbPlatformDictTypeByCode = getOne(new LambdaQueryWrapper<PlatformDictType>().eq(PlatformDictType::getDictCode, platformDictType.getDictCode()));
        if (ObjectUtil.isNotEmpty(dbPlatformDictTypeByCode)) {
            throw ServiceException.build(platformDictType.getDictName() + "该字典类型的标识重复");
        }

        // name 必须唯一
        PlatformDictType dbPlatformDictTypeByName = getOne(new LambdaQueryWrapper<PlatformDictType>().eq(PlatformDictType::getDictName, platformDictType.getDictName()));
        if (ObjectUtil.isNotEmpty(dbPlatformDictTypeByName)) {
            throw ServiceException.build(platformDictType.getDictName() + "该字典类型的名称重复");
        }

        platformDictType.setDictType(strUtils.createNo("DictType"));
        platformDictType.setTenantId(tokenUtils.getTenantId());
        return save(platformDictType);
    }

    /**
     * 多选级联删除字典类型
     *
     * @param dictIdList 字典类型ID列表
     * @return 是否成功
     */
    @Override
    public Boolean del(List<String> dictIdList) {
        List<PlatformDictType> platformDictTypeList = list(new LambdaQueryWrapper<PlatformDictType>().in(PlatformDictType::getDictId, dictIdList));
        if (ObjectUtil.isEmpty(platformDictTypeList)) {
            throw ServiceException.build("数据库中不存在需要删除的记录");
        }

        PlatformTenant platformTenant = platformTenantService.getOne(new LambdaQueryWrapper<PlatformTenant>().eq(PlatformTenant::getTenantId, tokenUtils.getTenantId()));

        platformDictTypeList.forEach(platformDictType -> {
            if ("PLATFORM_DICT".equals(platformDictType.getDictType())) {
                if (ObjectUtil.isEmpty(platformTenant)) {
                    throw ServiceException.build("获取租户失败");
                }
                if (!platformTenant.getIsPlatform()) {
                    throw ServiceException.build("非平台级租户不能删除平台级字典类型");
                }
            }
        });

        return removeBatchByIds(dictIdList);
    }

    /**
     * 修改字典类型信息
     *
     * @param platformDictTypeEditVo 字典类型视图对象
     * @return 是否成功
     */
    @Override
    public Boolean edit(PlatformDictTypeEditVo platformDictTypeEditVo) {
        if (ObjectUtil.isEmpty(platformDictTypeEditVo)) {
            throw ServiceException.build("字典类型对象无效");
        }

        PlatformDictType platformDictType = PlatformDictTypeBasic.INSTANCE.toPlatformDictType(platformDictTypeEditVo);
        if (ObjectUtil.isEmpty(platformDictType)) {
            throw ServiceException.build("字典类型对象无效");
        }

        PlatformDictType dbPlatformDictType = getOne(new LambdaQueryWrapper<PlatformDictType>().eq(PlatformDictType::getDictId, platformDictType.getDictId()));
        if (ObjectUtil.isEmpty(dbPlatformDictType)) {
            throw ServiceException.build(platformDictType.getDictName() + "该字典类型在数据库中不存在");
        }

        if ("PLATFORM_DICT".equals(dbPlatformDictType.getDictType())) {
            PlatformTenant platformTenant = platformTenantService.getOne(new LambdaQueryWrapper<PlatformTenant>().eq(PlatformTenant::getTenantId, tokenUtils.getTenantId()));
            if (ObjectUtil.isEmpty(platformTenant)) {
                throw ServiceException.build("获取租户失败");
            }
            if (!platformTenant.getIsPlatform()) {
                throw ServiceException.build("非平台级租户不能修改平台级字典类型");
            }
        }

        // Code 必须唯一
        if (!platformDictType.getDictCode().equals(dbPlatformDictType.getDictCode())) {
            PlatformDictType dbPlatformDictTypeByCode = getOne(new LambdaQueryWrapper<PlatformDictType>().eq(PlatformDictType::getDictCode, platformDictType.getDictCode()));
            if (ObjectUtil.isNotEmpty(dbPlatformDictTypeByCode)) {
                throw ServiceException.build(platformDictType.getDictName() + "该字典类型的标识重复");
            }
        }

        // name 必须唯一
        if (!platformDictType.getDictName().equals(dbPlatformDictType.getDictName())) {
            PlatformDictType dbPlatformDictTypeByName = getOne(new LambdaQueryWrapper<PlatformDictType>().eq(PlatformDictType::getDictName, platformDictType.getDictName()));
            if (ObjectUtil.isNotEmpty(dbPlatformDictTypeByName)) {
                throw ServiceException.build(platformDictType.getDictName() + "该字典类型的名称重复");
            }
        }

        BeanUtil.copyProperties(platformDictType, dbPlatformDictType, true);
        return updateById(dbPlatformDictType);
    }

    /**
     * 根据ID获取字典类型详情
     *
     * @param dictId 字典类型ID
     * @return 字典类型详情
     */
    @Override
    public PlatformDictTypeQueryDto info(String dictId) {
        PlatformDictType platformDictType = getOne(new LambdaQueryWrapper<PlatformDictType>().eq(PlatformDictType::getDictId, dictId));
        return PlatformDictTypeBasic.INSTANCE.toPlatformDictTypeQueryDto(platformDictType);
    }

    /**
     * 分页查询字典类型列表
     *
     * @param platformDictTypeQueryVo 字典类型视图对象
     * @return 分页字典类型列表
     */
    @Override
    public PageData<PlatformDictTypeQueryDto> pageList(PlatformDictTypeQueryVo platformDictTypeQueryVo) {
        Page<PlatformDictType> page = startPage();
        List<PlatformDictType> platformDictTypeList = platformDictTypeMapper.pageList(PlatformDictTypeBasic.INSTANCE.toPlatformDictType(platformDictTypeQueryVo), page);
        List<PlatformDictTypeQueryDto> platformDictTypeQueryDtoList = PlatformDictTypeBasic.INSTANCE.toPlatformDictTypeQueryDtoList(platformDictTypeList);
        return PageData.build(new Page<>(page.getCurrent(), page.getSize(), page.getTotal()), platformDictTypeQueryDtoList);
    }

}
